package rsa

import (
	"bytes"
	"crypto/rsa"
	"errors"
	"github.com/sirupsen/logrus"
	"io/ioutil"
)

const PirvateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyI1gGkMZEYq2yKyIejlmRzV445gsBXzt6EOtduJYbfTi5Ik+
KtEbaIKxkdb7q256fSu6VwmozAPlR9E8skXZJR6wqCQtb54GwVj07ou9qSP1g266
E33zaYDKPoYRtH96bXkS99nUVFlssXX8UfRkHlWHywpSNL19vQPuBXajEWvPdwqm
sf8MZbT9t0NIrGNKnOCH+PbeXjYuubXh6FSpT5rqzo/yqNiwwJmTKy6OrVs0l+cO
Id4LMVH/AiaG6cQSd7vRfbaY9JWsMBzTye41nZYZ1YbG/KCKODFS46LiwvKCAWuJ
sFr+xvkjFIHZTKRx2Nmtx04L3IL7+4B9paGoBQIDAQABAoIBABNWRlDh7VXaqRsa
P6KBTFJLXpebQYtZ61p8xAn1cw9PEF12ui7IsLrX9yUXtHZoFZliEPp5bPQW4BGX
pCGQSIqitefQbS0Y8I/N8vfZM3VOiUqd74UXnNOsXlO++5AKxpQtm12YfDeR08Ac
nzKLvOeL2acDHMAHEUubSGTwdnKkZbKlVjjuus5+44HQpIXtquk8X7V79pAcJMkx
EzW/6DoLM8roXNqPt0LYaYXxEyxxfPxPN98yx6wOBVazy2WXKRW0QZ82ZXKkKbdW
kdByJbx28dIZ8ySBUo/lVC0/xT+BXpMS22m0bVY6EHW1ZMaBQWnZ+HhCu0hyt6vY
GAh0X5UCgYEA0thhjImEphXJRp+ueflOU4acx2q5ypjh8djjmw/PCKLF5iWyLDqM
VF7JggZI8TP1/rWpv5P4hamOVvMbdm/87uXssnHai1i3/mJSSjslqi0DbcnJmTvJ
0S0zgWr5h//t42wKa2oE7TXE8c1BUba+QufMrQMU1qES6Oz84+MReQMCgYEA84Cu
AnJ/MNOEu1FD7iehGvHVCHiy96bqdphj511HCVJPK7WfHJBjDiEWLfmQiKExS9mP
vjDFmlHvb0/G9VtpSLmo55C9mfGGj+KaZusxyhaRCjxx0K1VUolvp/Z/CgI7wQq6
L6HHqib2ldcUBuvTTsfAtFmgVNMocW26gBfd2FcCgYAH+OKHW9PGK+C2aOdB+Wk6
w0Y+TAzGWk2AxYClpk1fuDffYeGAxp3zurnHztEHPb25ackHU2L8OtME+qA5NDbO
Gad/f8qRpkMevTz7TY05CAavKggTYS1aWWkvJYpV2Bl4lec29IVHKtdNhUNJAa3j
/bvBdvJcwy5h3EQbocRRXQKBgQDTjoogUC/XUP4x7JHzWPTsvw0SViNPbPKp5Q5v
VihAngVw+VPq8jtNbEuj1/7N5hY5SyVK3X7g66z17b7zLt9TMxLfVW6VUDVTz1HM
dy0D4gVTel58KgxGMGgU6uFG5dfaiSJn/cvGNiHo3ztkJAGroXr4diIJcIfjvKzb
W2D/8wKBgQCCq904b38HHouWbbaSOZ5SnfI2uJwaKBvYqjZLV/IjLrmEaHvBjDvq
/zpsZf7PsjB7pNZvfpXPcXdsj3gIdV4khiA227HcHyZOSvLfBill6yI1J6jDkS9C
wiKTpVIC7ThQcM2tVd6HL75glSOWQeweUl4I2AmtU/xC4hSSRGsY+g==
-----END RSA PRIVATE KEY-----`

const PublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyI1gGkMZEYq2yKyIejlm
RzV445gsBXzt6EOtduJYbfTi5Ik+KtEbaIKxkdb7q256fSu6VwmozAPlR9E8skXZ
JR6wqCQtb54GwVj07ou9qSP1g266E33zaYDKPoYRtH96bXkS99nUVFlssXX8UfRk
HlWHywpSNL19vQPuBXajEWvPdwqmsf8MZbT9t0NIrGNKnOCH+PbeXjYuubXh6FSp
T5rqzo/yqNiwwJmTKy6OrVs0l+cOId4LMVH/AiaG6cQSd7vRfbaY9JWsMBzTye41
nZYZ1YbG/KCKODFS46LiwvKCAWuJsFr+xvkjFIHZTKRx2Nmtx04L3IL7+4B9paGo
BQIDAQAB
-----END PUBLIC KEY-----`

const LDPublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHoeWqvv5vOUJWO0ABP1
XoH6Jt85DVZ/ONVhcoMd7862KUzIEX6aKNB52FBTy+TlMOxGXTm50HiZI8uk7jbi
hSl8J+Ioi6TiC8Dmh4YJEwUBkLhsurgHegkAbicIBPt2kSBjvbrA0Jrh7TcZfx2K
vVwQ9J4voEVgr/f2ZTqHVBD3PTIzTYQkA52/QAqKOqe9VHbFw/GATCZr5YOP6aUG
uJRX6k4s6cIMtO617bZAu5jYZThCqw2w4QUe8G0LRrjbRwLyOFLO3Z9xZ9UkHVvu
2Wy0NbOD6WavLjSBxFpAXd0itaaQHzt1EptRLdDRtjM7j2V9uWZDqJM1+LknHaFb
zQIDAQAB
-----END PUBLIC KEY-----`

var RSA = &RSASecurity{}

type RSASecurity struct {
	pubStr string          //公钥字符串
	priStr string          //私钥字符串
	pubKey *rsa.PublicKey  //公钥
	priKey *rsa.PrivateKey //私钥
}

func Setup() {
	err := RSA.SetPrivateKey(PirvateKey)
	if err != nil {
		logrus.Infof("秘钥设置失败: %v", err)
	}
	err = RSA.SetPublicKey(LDPublicKey)
	if err != nil {
		logrus.Infof("公钥设置失败: %v", err)
	}
}

// SetPublicKey 设置公钥
func (r *RSASecurity) SetPublicKey(pubStr string) (err error) {
	r.pubStr = pubStr
	r.pubKey, err = r.GetPublickey()
	return err
}

// SetPrivateKey 设置私钥
func (r *RSASecurity) SetPrivateKey(priStr string) (err error) {
	r.priStr = priStr
	r.priKey, err = r.GetPrivatekey()
	return err
}

// GetPrivatekey *rsa.PublicKey
func (r *RSASecurity) GetPrivatekey() (*rsa.PrivateKey, error) {
	return getPriKey([]byte(r.priStr))
}

// GetPublickey *r.PrivateKey
func (r *RSASecurity) GetPublickey() (*rsa.PublicKey, error) {
	return getPubKey([]byte(r.pubStr))
}

// PubKeyENCTYPT 公钥加密
func (r *RSASecurity) PubKeyENCTYPT(input []byte) ([]byte, error) {
	if r.pubKey == nil {
		return []byte(""), errors.New(`Please set the public key in advance`)
	}
	output := bytes.NewBuffer(nil)
	err := pubKeyIO(r.pubKey, bytes.NewReader(input), output, true)
	if err != nil {
		return []byte(""), err
	}
	return ioutil.ReadAll(output)
}

// PubKeyDECRYPT 公钥解密
func (r *RSASecurity) PubKeyDECRYPT(input []byte) ([]byte, error) {
	if r.pubKey == nil {
		return []byte(""), errors.New(`Please set the public key in advance`)
	}
	output := bytes.NewBuffer(nil)
	err := pubKeyIO(r.pubKey, bytes.NewReader(input), output, false)
	if err != nil {
		return []byte(""), err
	}
	return ioutil.ReadAll(output)
}

// PriKeyENCTYPT 私钥加密
func (r *RSASecurity) PriKeyENCTYPT(input []byte) ([]byte, error) {
	if r.priKey == nil {
		return []byte(""), errors.New(`Please set the private key in advance`)
	}
	output := bytes.NewBuffer(nil)
	err := priKeyIO(r.priKey, bytes.NewReader(input), output, true)
	if err != nil {
		return []byte(""), err
	}
	return ioutil.ReadAll(output)
}

// PriKeyDECRYPT 私钥解密
func (r *RSASecurity) PriKeyDECRYPT(input []byte) ([]byte, error) {
	if r.priKey == nil {
		return []byte(""), errors.New(`Please set the private key in advance`)
	}
	output := bytes.NewBuffer(nil)
	err := priKeyIO(r.priKey, bytes.NewReader(input), output, false)
	if err != nil {
		return []byte(""), err
	}

	return ioutil.ReadAll(output)
}
